from  deslab import *

"""
This is the script for the computation of minimal event bases that ensure diagnosability.
The algorithms are part of the paper:
(1) Basilio, J., Lima, S., Lafortune, S.,, e Moreira, M. (2012), "Computation of minimal
event bases that ensure diagnosability," Discrete Event Dynamic Systems, 
"""

from minimal_basis import *
set = frozenset


def find_Sigma_IES_Obs(XDS, XST, ind_states , So, Sop):
    """This function calculates the innovative event set
    Sigma_ies^0 for observable cycles according to algorithm 3
     of reference (1).          
     """ 
    # Step 1: 
    #   Compute $S\prime_d$       
    Sd = [i.s for i in XDS if i.x_d in ind_states] 
    # Detecting "indeterminate" states      
    S_YN = [i for i in XST if i.xp_d in ind_states]  
    # Step 2: 
    #   Calculating $S_Y$ and $So_Y$       
    S_Y = set([i for i in S_YN if YN_type(i.x_d) == 'Y'])
    So_Y = set([i.s for i in S_Y if any(e in Sop for e in i.cycle)])
    #   Calculating $S_N$ e $So_Y$
    S_N = set([i for i in S_YN if YN_type(i.x_d) <> 'Y'])
    So_N = set([i.s for i in S_N if any(e in Sop for e in i.cycle) and YN_type(i.x_d) <> 'Y'])
    # Step 3:
    Sigma_ies_i = set()
    for s_i in Sd:
        # Step 3 : 
 
        #    compute $S^o_{Y,i}$ and $S^o_{N,i}$        
        So_Y_i = set([sy for sy in So_Y if s_i in prefixes(proj(sy,Sop))])      # dont forget to test <= instead of prefixes
        So_N_i = set([sn for sn in So_N if s_i in prefixes(proj(sn,Sop))])
        # Step 4 : 
        #    compute $\Sigma_{Y,i}^k$ and $\Sigma_{N,i}^l$
        SigmaY_i = set([set([e for e in sy if e in So-Sop])  for sy in So_Y_i if any(k in So-Sop for k in sy)])     
        SigmaN_i = set([set([e for e in sn if e in So-Sop])  for sn in So_N_i if any(k in So-Sop for k in sn)])          
        # Step 5:
        #   form the sets $\Sigma^o_{ies, Yi}$, $\Sigma^o_{ies, Yi}$
        #   and set the right stratification
        Sigmao_iesY_i = stratify_sigma(SigmaY_i)
        Sigmao_iesN_i = stratify_sigma(SigmaN_i)   
        # Compute $\Sigma^o_{ies}$ by taking the union of the former sets           
        Sigma_ies_i |=  set([ Sigmao_iesY_i | Sigmao_iesN_i])          
    if Sigma_ies_i:
        # Step 6:
        #    calculating  $\Sigma^o_{ies}$ as the product of
        #    the collection if $\Sigma^o_{ies,i} \neq \emptyset$   
        Sigma_ies = prodcollection(Sigma_ies_i) 
    else:
        # otherwise $\Sigma^o_{ies}=\{\emptyset\}$
        Sigma_ies = set([set()])    
    # Step 7: 
    #   find the minimals of the poset
    Sigma_ies = minimals_of_poset(Sigma_ies)
    return Sigma_ies, S_Y, S_N 







"""   TESTING CODE    """

a,b,c,d,e,sf = syms('a b c d e f')
G=load('G_example7')
Gd = load('Gd_example7')
Sop=set([b])
Gdprime = diagnoser(G,sf,Sop)
So = G.Sigobs # set Sigma_o
Gtest = Gdprime//Gd 
I = find_indeterminate_states(G, Gdprime, sf)  
XDS, tree_1 = find_XDS(Gdprime)
XST, tree_2 = prime_paths_cycle_smax(Gtest)  
Sigma_ies, S_Y, S_N=find_Sigma_IES_Obs(XDS, XST, I, So, Sop)

"""
drawgraph(tree_1,'XDS')
drawgraph(tree_2,'XST')
"""









































